package com.nmf.site.common.aop;

import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.Validator;

import com.nmf.pc.enums.RspStatus;
import com.nmf.pc.vo.ReturnResult;
import com.nmf.site.common.mapper.JsonMapper;

@Component
@Aspect
public class ParameterValidator {
	private Logger log = LoggerFactory.getLogger(ParameterValidator.class);
	@Autowired
	Validator validator;
	
	@Around(value = "@annotation(org.springframework.web.bind.annotation.RequestMapping)", argNames = "jp")
	public Object basicParameterCheck(ProceedingJoinPoint jp) throws Throwable {
		Object[] args = jp.getArgs();
		long time = System.currentTimeMillis();
		String str = "";
		for (Object arg : args) {
			if (arg instanceof BindingResult) {
				ReturnResult rs = new ReturnResult();
				rs.setStatus(RspStatus.PARAMERROR.value);
				BindingResult result = BindingResult.class.cast(arg);
				if (result.hasErrors()) {
					Map<String, String> errMsgMap = new HashMap<>(result.getErrorCount());
					for (FieldError error : result.getFieldErrors()) {
						errMsgMap.put(error.getField(), error.getDefaultMessage());
					}
					rs.setMessage(RspStatus.PARAMERROR.name + errMsgMap.toString());
					log.error(errMsgMap.toString());
					return rs;
				}
				continue;
			}
			if(arg instanceof HttpServletRequest) {
				HttpServletRequest request = (HttpServletRequest)arg;
				String id = "";
				str = str+"用户【" + id + "】" + request.getRequestURL().toString() + "?" + makeParamLog(request) + "\t";
			}
		}

		Object obj = jp.proceed();
		try {
			long dtime = (System.currentTimeMillis()-time);
			log.info("耗时【"+dtime+"】"+str+"返回为："+JsonMapper.getInstance().toJson(obj));
		}catch(Exception e) {
			log.warn("JSON 日志解析错误",e);
		}
		return obj;
	}
	private String makeParamLog(ServletRequest request) {
		StringBuilder sb = new StringBuilder();
		Enumeration<String> parameterNames = request.getParameterNames();
		while (parameterNames.hasMoreElements()) {
			String paramName = parameterNames.nextElement();
			String[] paramValues = request.getParameterValues(paramName);
			if (paramValues != null) {
				String valStr = "";
				if (paramValues.length == 1) {
					valStr = paramValues[0];
				} else if (paramValues.length > 1) {
					valStr = Arrays.toString(paramValues);
				}
				sb.append(paramName).append("=").append(valStr);
				if (parameterNames.hasMoreElements()) {
					sb.append("&");
				}
			}
		}
		return sb.toString();
	}
}
